package com.onec.service.channel.service.api;


import com.onec.service.api.dto.request.channel.ChannelMerchantReq;
import com.onec.service.api.dto.request.route.RouteReq;
import com.onec.service.api.dto.response.channel.ChannelMerchantResp;
import com.onec.service.api.dto.response.route.RouteResp;
import com.onec.service.api.enums.ProductEnum;
import com.onec.service.api.enums.StatusEnum;
import com.onec.service.api.enums.error.ChannelErrorEnum;
import com.onec.service.api.service.channel.ChannelMerchantApiService;
import com.onec.service.api.service.route.RouteRiskApiService;
import com.onec.service.channel.entity.ChannelInfo;
import com.onec.service.channel.entity.ChannelMerchant;
import com.onec.service.channel.entity.ChannelMerchantBusiness;
import com.onec.service.channel.service.ChannelInfoService;
import com.onec.service.channel.service.ChannelMerchantBusinessService;
import com.onec.service.channel.service.ChannelMerchantService;
import com.onec.service.channel.service.channel.base.BaseChannelMerchantService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import java.util.List;
import java.util.Optional;


/**
 * 一个通道会分配多个商户信息：channelFlag 唯一，同时也是spring 中 bean 的方法名字：
 * merchant_{channelFlag} 和 order_{channelFlag}
 *
 * @author onec
 * @see
 */
@Slf4j
@DubboService(version = "1.0.1", timeout = 6000)
public class ChannelMerchantApiServiceImpl implements ChannelMerchantApiService {


    @Autowired
    ChannelMerchantService channelMerchantService;
    @Autowired
    ChannelMerchantBusinessService channelMerchantBusinessService;
    @Autowired
    ChannelInfoService channelInfoService;
    @Autowired
    ApplicationContext applicationContext;

    @DubboReference(version = "1.0.1", timeout = 6000)
    RouteRiskApiService routeRiskApiService;

    private static final String MERCHANT_ = "merchant";

    private String getMerchantChannelFlag(String channelFlag) {
        return MERCHANT_ + channelFlag;
    }

    /**
     * 通道商户信息注册接口！
     *
     * @param channelMerchantReq
     * @return
     */
    @Override
    public ChannelMerchantResp register(ChannelMerchantReq channelMerchantReq) {

        RouteReq routeReq = new RouteReq();
        RouteResp routeResp = routeRiskApiService.getNeedRegisterChannelList(routeReq);
        if (routeResp.isSuccess()) {
            List<String> channelNoList = routeResp.getChannelNoList();
            for (String channelNo : channelNoList) {
                ChannelInfo channelInfo = channelInfoService.getChannelInfoByNo(channelNo);
                String channelBeanName = this.getMerchantChannelFlag(channelInfo.getChannelFlag());
                BaseChannelMerchantService baseMerchantService = applicationContext
                        .getBean(channelBeanName, BaseChannelMerchantService.class);
                boolean needRegister = baseMerchantService.needRegister();

                log.info("商户注册：通道：{}，是否需要注册：{}", channelMerchantReq.getChannelNo(), needRegister);
                if (!needRegister) {
                    // return ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.NO_REGISTER_ERROR);
                    continue;
                }
                ChannelMerchant channelMerchant = channelMerchantService
                        .findByChannelIdProductMerchantNo(channelInfo.getId(), channelMerchantReq.getMerchantNo(), ProductEnum.DEFAULT);
                if (Optional.ofNullable(channelMerchant).isPresent()) {
                    //return ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.CHANNEL_MERCHANT_EXIST_ERROR);
                    if (StatusEnum.isSuccess(channelMerchant.getStatus()) || StatusEnum.isFailed(channelMerchant.getStatus())) {
                        continue;
                    }
                }
                // 多通道批量报备不记录结果
                ChannelMerchantResp channelMerchantResp = baseMerchantService.register(channelMerchantReq, channelInfo);

            }

        }
        return ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.SUCCESS);
    }

    /**
     * 通道产品：（业务开通接口）
     * 通道业务编号对应唯一个商户业务编号！
     *
     * @param channelMerchantReq
     * @return
     */
    @Override
    public ChannelMerchantResp openProduct(ChannelMerchantReq channelMerchantReq) {
        ChannelInfo channelInfo = channelInfoService.getChannelInfoByNo(channelMerchantReq.getChannelNo());
        ChannelMerchantBusiness channelMerchantBusiness = Optional
                .ofNullable(channelMerchantBusinessService
                        .findByMerchantNoChannelIdBusinessNo(channelMerchantReq.getMerchantNo(),
                                channelInfo.getId(), channelMerchantReq.getBusinessNo()))
                .orElse(channelMerchantBusinessService.create(channelInfo, channelMerchantReq));
        log.info("通道产品开通【openProduct】 ：通道编号：{}，业务编号：{},开通状态：{}", channelInfo.getNo(),
                channelMerchantReq.getBusinessNo(), channelMerchantBusiness.getStatus());
        if (StatusEnum.isSuccess(channelMerchantBusiness.getStatus())) {
            return ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.CHANNEL_MERCHANT_EXIST_ERROR);
        }

        String channelBeanName = this.getMerchantChannelFlag(channelInfo.getChannelFlag());
        BaseChannelMerchantService baseMerchantService = applicationContext
                .getBean(channelBeanName, BaseChannelMerchantService.class);
        return baseMerchantService.productOpen(channelMerchantReq, channelInfo);
    }

    /**
     * 修改通道商户费率:
     * 不同通道有不同修改方式！修改失败将通道商户业务停掉！
     *
     * @param channelMerchantReq
     * @return
     */
    @Override
    public ChannelMerchantResp updateMerchantFee(ChannelMerchantReq channelMerchantReq) {
        ChannelInfo channelInfo = channelInfoService.getChannelInfoByNo(channelMerchantReq.getChannelNo());
        String channelBeanName = this.getMerchantChannelFlag(channelInfo.getChannelFlag());
        BaseChannelMerchantService baseMerchantService = applicationContext
                .getBean(channelBeanName, BaseChannelMerchantService.class);
        return baseMerchantService.updateMerchantFee(channelMerchantReq, channelInfo);
    }

    /**
     * 变更商户结算卡！
     * 变更失败将通道商户停掉！
     *
     * @param channelMerchantReq
     * @return
     */
    @Override
    public ChannelMerchantResp updateMerchantSettle(ChannelMerchantReq channelMerchantReq) {
        ChannelInfo channelInfo = channelInfoService.getChannelInfoByNo(channelMerchantReq.getChannelNo());
        String channelBeanName = this.getMerchantChannelFlag(channelInfo.getChannelFlag());
        BaseChannelMerchantService baseMerchantService = applicationContext
                .getBean(channelBeanName, BaseChannelMerchantService.class);
        return baseMerchantService.updateMerchantSettle(channelMerchantReq, channelInfo);
    }

    /**
     * 查询通道商户信息！
     *
     * @param channelMerchantReq
     * @return
     */
    @Override
    public ChannelMerchantResp queryMerchantApi(ChannelMerchantReq channelMerchantReq) {
        ChannelInfo channelInfo = channelInfoService.getChannelInfoByNo(channelMerchantReq.getChannelNo());
        String channelBeanName = this.getMerchantChannelFlag(channelInfo.getChannelFlag());
        BaseChannelMerchantService baseMerchantService = applicationContext
                .getBean(channelBeanName, BaseChannelMerchantService.class);
        return baseMerchantService.queryMerchantApi(channelMerchantReq, channelInfo);
    }

    /**
     * 查询通道商户业务余额！
     *
     * @param channelMerchantReq
     * @return
     */
    @Override
    public ChannelMerchantResp queryMerchantAmountApi(ChannelMerchantReq channelMerchantReq) {
        ChannelInfo channelInfo = channelInfoService.getChannelInfoByNo(channelMerchantReq.getChannelNo());
        String channelBeanName = this.getMerchantChannelFlag(channelInfo.getChannelFlag());
        BaseChannelMerchantService baseMerchantService = applicationContext
                .getBean(channelBeanName, BaseChannelMerchantService.class);
        return baseMerchantService.queryMerchantAmountApi(channelMerchantReq, channelInfo);
    }

    /**
     * 查询通道商户结算信息
     *
     * @param channelMerchantReq
     * @return
     */
    @Override
    public ChannelMerchantResp querySettleApi(ChannelMerchantReq channelMerchantReq) {
        ChannelInfo channelInfo = channelInfoService.getChannelInfoByNo(channelMerchantReq.getChannelNo());
        String channelBeanName = this.getMerchantChannelFlag(channelInfo.getChannelFlag());
        BaseChannelMerchantService baseMerchantService = applicationContext
                .getBean(channelBeanName, BaseChannelMerchantService.class);
        return baseMerchantService.querySettleApi(channelMerchantReq, channelInfo);
    }
}
